package com.ceadeal.javafxboot.ctrl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.arcsoft.face.FaceInfo;
import com.ceadeal.javafxboot.config.TowerGuardConfig;
import com.ceadeal.javafxboot.entity.HelmetImage;
import com.ceadeal.javafxboot.mapper.FaceUserInfoMapper;
import com.ceadeal.javafxboot.service.IArcSoftService;
import com.ceadeal.javafxboot.util.FaceHelper;

import de.felixroske.jfxsupport.FXMLController;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.SplitPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Window;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;

/**
 * 主界面控制器
 *
 * @author westinyang
 * @date 2019/4/23 2:01
 */
@Slf4j
@FXMLController
public class MainCtrl implements Initializable{

    // 主容器
    @FXML
    public SplitPane rootPane;
    Window window;// = rootPane.getScene().getWindow();
    @FXML
    public Button btnAlert, btnChooseFile;
    @FXML
    public ImageView OriginalImageView;
    @FXML
    public AnchorPane OriginalAnchorPane;
    @Autowired
    FaceUserInfoMapper faceUserInfoMapper;
    @Autowired
    IArcSoftService arcSoftService;

    @Autowired
    FaceHelper faceHelper;
    @Autowired
    TowerGuardConfig towerGuardConfig;
    InetAddress localAddr;
    DatagramSocket socketWithHelmetServer;
    File currentImagefile;//当前用于检测的图片
    String currentImageFileAbsolutePath;//用于检测的图片绝对路径
    int imageID=0;
    boolean listenRunning=true;
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        faceHelper.loadFaceUserInfos();//应用启动就加载人脸数据
        log.info("initialize: {}", location.getPath());
        try{
            localAddr = InetAddress.getByName("localhost");
            socketWithHelmetServer = new DatagramSocket(towerGuardConfig.getFaceDetectPort(), localAddr);
            socketWithHelmetServer.setReuseAddress(true);
        }
        catch (SocketException ex) {
            System.out.println("create socket exception");
        }
        catch (UnknownHostException ex)
        {
            System.out.println("UnknownHostException exception");
        }
//        rootPane.heightProperty().addListener()
//        window = rootPane.getScene().getWindow();
//
        OriginalAnchorPane.heightProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                double f = newValue.doubleValue() / 1920;
                //设置图片的宽度
                OriginalImageView.setFitWidth(OriginalAnchorPane.getWidth());
            }
        });
        startReceiveCommand(socketWithHelmetServer);//开始接收安全帽检测数据

    }





    /**
     * 批量录入人脸数据库
     * @param actionEvent
     */
    public void onBatAddFace(ActionEvent actionEvent) throws InterruptedException {
//        Alert alert = new Alert(Alert.AlertType.INFORMATION);
//        alert.setContentText("当前时间：" + DateUtil.now());
//        alert.show();
//        FaceUserInfo faceUserInfo= FaceUserInfo.builder().name("gbg1").face_feature(new byte[10]).build();
//        List<FaceUserInfo> list = faceUserInfoMapper.selectAllFaceInfos();
//        faceUserInfoMapper.insertFaceInfo(faceUserInfo);
//        faceHelper.initFaceDB();
        File dir = chooseDirectory();
        faceHelper.registerFaces(dir);
    }

    /**
     * 弹出框按钮单击事件
     * @param actionEvent
     */
    public void onBtnRtsp(ActionEvent actionEvent) {
//        Alert alert = new Alert(Alert.AlertType.INFORMATION);
//        alert.setContentText("当前时间：" + DateUtil.now());
//        alert.show();
//        respGrabberServiceImpl.startGrabber(respGrabber, faceUserInfosInDB,filePath,respStopCondition,consumer1);
//        loadFaces();
    }
    /**
     * 选择单个图片文件进行安全帽检测：向python的安全帽检测程序发送一个消息，消息内容包括待检测的图片的地址
     * 安全帽检测程序会将这个地址和检测结果再发回给本程序
     * 这个图片地址也会作为检测结果集的key值
     * @param actionEvent
     */
    public void onBtnHelmet(ActionEvent actionEvent) {
//        Alert alert = new Alert(Alert.AlertType.INFORMATION);
//        alert.setContentText("当前时间：" + DateUtil.now());
//        alert.show();
        File file = getImageFile();
        String fileAbsolutePath = file == null ? "" : file.getAbsolutePath();

        if (file != null) {
            imageID++;
            HelmetImage helmetImage=new HelmetImage(imageID,fileAbsolutePath);
            String jsonHelmetImage = JSON.toJSONString(helmetImage);
            byte[] sendBuffer = jsonHelmetImage.getBytes(StandardCharsets.UTF_8);
            DatagramPacket packet = new DatagramPacket(sendBuffer, sendBuffer.length);
            packet.setPort(towerGuardConfig.getHelmetDetectPort());
            packet.setAddress(localAddr);
            try {
                socketWithHelmetServer.send(packet);//将图片文件路径发送给python的安全帽识别程序
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }

        }
    }

    /**
     * 接收控制指令
     */
    void startReceiveCommand(DatagramSocket socket) {
        Runnable listenLoop = new Runnable() {
            @Override
            public void run() {
                byte[] receiveBuffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(receiveBuffer, receiveBuffer.length);
                while (listenRunning) {
                    if (!socket.isClosed()) {
                        try {
                            socket.receive(packet);
                            System.out.printf("\n检测到的安全帽数量为："+new String(receiveBuffer,0,packet.getLength()));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        new Thread(listenLoop).start();


    }
    /**
     * 单图检测 选择单个图片文件
     * @param actionEvent
     */
    public void onBtnChooseFileClick(ActionEvent actionEvent) throws InterruptedException, ExecutionException, IOException {
        currentImagefile = getImageFile();
        currentImageFileAbsolutePath = currentImagefile == null ? "" : currentImagefile.getAbsolutePath();
        if (currentImagefile != null) {
            BufferedImage image = ImageIO.read(currentImagefile);
            Graphics g = image.getGraphics();
            g.setColor(Color.RED);
//            Alert alert = new Alert(Alert.AlertType.INFORMATION);
//            alert.setContentText("文件路径：" + fileAbsolutePath);
//            alert.show();
            //extractFaceFeature
//            List<FaceInfo> faceFeatures = arcSoftService.detectFaces(file);
//            Consumer<List<FaceUserInfo>> consumer = x->{
//                for (FaceUserInfo info:x
//                     ) {
//                    System.out.println(x.toString());
//                }
//            };
//            faceHelper.compareFace(file,consumer);

            List<FaceInfo> faceList = faceHelper.detectFaces(currentImagefile);
            if (faceList !=null)
                for (FaceInfo faceInfo :
                        faceList) {
                    com.arcsoft.face.Rect rectFace = faceInfo.getRect();
                    double x = OriginalAnchorPane.getLayoutX();
                    int width = rectFace.getRight()-rectFace.getLeft();
                    int height = rectFace.getBottom()-rectFace.getTop();
                    g.drawRect(rectFace.getLeft(),rectFace.getTop(),width,height);
                }
            String tempFilePath="e://temp.jpg";//d盘不知道为啥不行
            FileOutputStream out = new FileOutputStream(tempFilePath);
            ImageIO.write(image,"jpeg",out);//写回
            Image imageTemp = new Image("file:"+ tempFilePath);//网络图像文件前面加“http://”，而本地文件则要加“file:”
            OriginalImageView.setImage(imageTemp);
        }
    }



    /**
     * 选择一个图片文件
     * @return
     */
    private File getImageFile() {
        window = rootPane.getScene().getWindow();
        FileChooser fileChooser = new FileChooser();
        // 文件类型过滤器
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("图片 files (*.jpg, *.png)", "*.jpg", "*.png");
        fileChooser.getExtensionFilters().add(filter);
        // ...
        File file = fileChooser.showOpenDialog(window);
        String fileName = file == null ? "" : file.getName();
        return file;
    }

    /**
     * 选择一个目录
     * @return
     */
    private File chooseDirectory()
    {
        Window window = rootPane.getScene().getWindow();
        DirectoryChooser fileChooser = new DirectoryChooser();
        // ...
        File file = fileChooser.showDialog(window);
        return file;
    }


}
